﻿using System;
using System.Reflection;

using SBPweb.Forge.Contracts.Events;

using SBPweb.Communication.Client.Library.Xmpp;
using SBPweb.Communication.Client.Library.Xmpp.Contacts;
using SBPweb.Communication.Client.Library.Xmpp.Configuration;
using SBPweb.Communication.Client.Library.Xmpp.Conversations;

using SBPweb.Communication.Shared.Library;
using SBPweb.Communication.Shared.Library.Contacts;
using SBPweb.Communication.Shared.Library.Conversations;

using SBPweb.PROvibe.Business.Server.Library.Modularity;

namespace SBPweb.PROvibe.Modules.Server.Communication.Xmpp
{

    public class Module : ModuleBase
    {

        #region Private fields

        private Messenger messenger;

        #endregion

        #region Constructor logic

        public Module(SBPweb.Forge.Modules.Modularity.IModuleHost parent)
            : base(parent)
        {
            messenger = new Messenger();
            messenger.Initialized += new EventHandler(messenger_Initialized);
            messenger.Connections.Connecting += new EventHandler(Connections_Connecting);
            messenger.Connections.Connected += new EventHandler(Connections_Connected);
            messenger.Connections.Disconnecting += new EventHandler<CancelEventArgs>(Connections_Disconnecting);
            messenger.Connections.Disconnected += new EventHandler(Connections_Disconnected);
            messenger.Connections.PresenceStateChanged += new EventHandler<SBPweb.Communication.Shared.Library.Contacts.ContactPresenceStateBaseEventArgs>(Connections_PresenceStateChanged);
            messenger.Contacts.ContactListRequested += new EventHandler(Contacts_ContactListRequested);
            messenger.Contacts.ContactListReceived += new EventHandler(Contacts_ContactListReceived);
            messenger.Contacts.ContactPresenceChanged += new EventHandler<ContactPresenceStateBaseEventArgs>(Contacts_ContactPresenceChanged);
            messenger.Conversations.ConversationOpened += new EventHandler<SBPweb.Communication.Shared.Library.Conversations.ConversationEventArgs>(Conversations_ConversationOpened);
            (messenger.Conversations as ConversationManager).FindPublicConferencesRequested += new EventHandler(Conversations_FindPublicConferencesRequested);
            (messenger.Conversations as ConversationManager).FindPublicConferencesReceived += new EventHandler(Conversations_FindPublicConferencesReceived);
            (messenger.Configurations as ConfigurationManager).AssemblyResolvingFailed += new EventHandler<ConfigurationManager.AssemblyResolvingEventArgs>(Configurations_AssemblyResolvingFailed);

            Services.Put<MessengerBase>(messenger);
        }

        #endregion

        #region Methods

        protected override void OnInitialize()
        {
            messenger.Initialize();
        }

        protected override void OnTerminate()
        {
            messenger.Terminate();
        }

        #region Messenger events

        private void messenger_Initialized(object sender, EventArgs e)
        {
            messenger.Connections.Connect("test001", "a");
        }

        #region Configurations

        private void Configurations_AssemblyResolvingFailed(object sender, ConfigurationManager.AssemblyResolvingEventArgs e)
        {
            e.Assembly = Assembly.GetExecutingAssembly();
        }

        #endregion

        #region Connections

        private void Connections_Connecting(object sender, EventArgs e)
        {
            System.Console.WriteLine(string.Format("Connecting to {0}:{1} with user {2}...", messenger.Connections.Configuration.Server, messenger.Connections.Configuration.Port, messenger.Connections.UserName));
        }

        private void Connections_Connected(object sender, EventArgs e)
        {
            System.Console.WriteLine("Connected successfully.");
            System.Console.WriteLine("Press ESC key to disconnect...");
        }

        private void Connections_Disconnecting(object sender, CancelEventArgs e)
        {
            System.Console.WriteLine("Disconnecting...");
        }

        private void Connections_Disconnected(object sender, EventArgs e)
        {
            System.Console.WriteLine("Disconnected gracefully.");
        }

        private void Connections_PresenceStateChanged(object sender, ContactPresenceStateBaseEventArgs e)
        {
            System.Console.WriteLine(string.Format("State changed to {0}.", e.State.ToString()));
        }

        #endregion

        #region Contacts

        private void Contacts_ContactListRequested(object sender, EventArgs e)
        {
            System.Console.WriteLine("Contact list requesting...");
        }

        private void Contacts_ContactListReceived(object sender, EventArgs e)
        {
            foreach (Contact c in messenger.Contacts.ContactList)
            {
                System.Console.WriteLine(string.Format("\t{0}", c));
            }
            System.Console.WriteLine("Contact list received!");
        }

        private void Contacts_ContactPresenceChanged(object sender, ContactPresenceStateBaseEventArgs e)
        {
            System.Console.WriteLine(string.Format("Contact {0} has changed her/his state to {1}.", e.Contact, e.State));
        }

        #endregion

        #region Conversations

        private void Conversations_FindPublicConferencesRequested(object sender, EventArgs e)
        {
            System.Console.WriteLine("Public conference list requesting...");
        }

        private void Conversations_FindPublicConferencesReceived(object sender, EventArgs e)
        {
            foreach (Contact c in (messenger.Conversations as ConversationManager).PublicConferences)
            {
                System.Console.WriteLine(string.Format("\t{0}", c));
            }
            System.Console.WriteLine("Public conference list received!");
            messenger.Conversations.OpenConference("PROvibe_NET_Host");
        }

        private void Conversations_ConversationOpened(object sender, ConversationEventArgs e)
        {
        }

        #endregion

        #endregion

        #endregion

    }

}